package com.zenghus.spring.formework.context.support;

import com.zenghus.spring.formework.bean.BeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @author zenghu
 * @date 2018/5/1 12:12
 */
//对配置文件进行查找，读取，解析
public class BeanDefinitionReader {

    private Properties config=new Properties();

    //存放配置文件加载的class
    private List<String> registyBeanClasses=new ArrayList<String>();

    //在配置文件中需要用来获取自动扫描的包名的key
    private final String SCAN_PACKAGE="scanPackage";

    public BeanDefinitionReader(String ...locations){
        //根据路径加载配置文件
        InputStream is=this.getClass().getClassLoader().getResourceAsStream(locations[0].replace("classpath:",""));
        try {
            config.load(is);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //扫描配置文件中的文件
        doScanner(config.getProperty(SCAN_PACKAGE));
    }

    //返回配置文件中相关的所有class
    public List<String> loadBeanDefinitions(){
        return this.registyBeanClasses;
    }

    //递归扫描相关的class，并且保存起来
    private void doScanner(String packageName){
        //递归获取包下所有文件
        URL url=this.getClass().getClassLoader().getResource("/"+packageName.replaceAll("\\.", "/"));
        File dir=new File(url.getFile());
        for (File file : dir.listFiles()) {
            if(file.isDirectory()){//判断是否是文件夹，如果是的话就递归
                doScanner(packageName+"."+file.getName());
            }else{
                //获取文件名称
                String className=packageName+"."+file.getName().replace(".class", "");
                registyBeanClasses.add(className);
            }
        }
    }


    //每注册一个classname就返回一个beanDefinition
    //beanDefinition是自己对对象的封装
    public BeanDefinition registerBean(String className){
        if(this.registyBeanClasses.contains(className)){
            BeanDefinition beanDefinition=new BeanDefinition();
            beanDefinition.setBeanClassName(className);
            beanDefinition.setFactoryBeanName(lowerFirst(className.substring(className.lastIndexOf(".")+1)));
            return beanDefinition;
        }
        return null;
    }

    public Properties getConfig() {
        return config;
    }

    //首字母小写
    private String lowerFirst(String str){
        char[] chars=str.toCharArray();
        chars[0]+=32;
        return String.valueOf(chars);
    }
}
